package com.game.sample.helper;


import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import com.game.sample.Sample;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SampleReflectHelper {
    public static final Logger log = LoggerFactory.getLogger(SampleReflectHelper.class);

    public static List<Sample> resolveSample(Class<?> clazz, String[] attributeNames, List<String[]> attributeValues) {
        List<Sample> samples = new ArrayList<>(attributeValues.size());
        Sample sample = null;
        int n = 4;
        for (String[] values : attributeValues) {
            n++;
            try {
                sample = (Sample)clazz.newInstance();
            } catch (Exception e) {
                log.warn("", e);
            }
            if (sample == null)
                continue;
            for (int i = 0; i < attributeNames.length; i++) {
                String attributeName = attributeNames[i].trim();
                String attributeValue = null;
                if (i < values.length)
                    attributeValue = values[i].trim();
                if (!attributeNames[i].isEmpty() && attributeValue != null && !attributeValue.isEmpty())
                    if (!sample.setAttribute(attributeName, attributeValue) && !set(sample, attributeName, attributeValue))
                        log.warn("{},fieldName={},value={}", new Object[] { clazz.getName(), attributeName, attributeValue });
            }
            if (sample.sid > 0)
                samples.add(sample);
        }
        return samples;
    }

    private static boolean set(Object instance, String fieldName, String value) {
        try {
            Field field = instance.getClass().getField(fieldName);
            Class<?> fieldClazz = field.getType();
            if (fieldClazz == List.class) {
                Type type = field.getGenericType();
                List<Object> list = (List)field.get(instance);
                if (list == null) {
                    list = new ArrayList();
                    field.set(instance, list);
                }
                Object vobj = value;
                if (type instanceof ParameterizedType) {
                    ParameterizedType pt = (ParameterizedType)type;
                    Class<?> genericClazz = (Class)pt.getActualTypeArguments()[0];
                    vobj = parseValue(genericClazz, value);
                }
                list.add(vobj);
            } else {
                Object vobj = parseValue(fieldClazz, value);
                field.set(instance, vobj);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("", e);
            return false;
        }
    }

    public static Object parseValue(Type fieldClazz, String value) {
        if (fieldClazz == String.class)
            return value;
        if (fieldClazz == int.class || fieldClazz == Integer.class)
            return Integer.valueOf(Double.valueOf(value).intValue());
        if (fieldClazz == byte.class || fieldClazz == Byte.class)
            return Byte.valueOf(Double.valueOf(value).byteValue());
        if (fieldClazz == boolean.class || fieldClazz == Boolean.class) {
            if (value == null || value.isEmpty() || "false".equalsIgnoreCase(value) || "0.0".equals(value) || "0".equals(value))
                return Boolean.valueOf(false);
            return Boolean.valueOf(true);
        }
        if (fieldClazz == short.class || fieldClazz == Short.class)
            return Short.valueOf(Double.valueOf(value).shortValue());
        if (fieldClazz == long.class || fieldClazz == Long.class)
            return Long.valueOf(Double.valueOf(value).longValue());
        if (fieldClazz == float.class || fieldClazz == Float.class)
            return Float.valueOf(value);
        if (fieldClazz == double.class || fieldClazz == Double.class)
            return Double.valueOf(value);
        return value;
    }
}
